home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / util / dres.2 < prev    next >
Text File  |  1988-10-25  |  52KB  |  2,070 lines

  1. Path: xanth!nic.MR.NET!umn-d-ub!rutgers!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i017:  dres - an object-oriented resource library, Part02/03
  5. Message-ID: <9822@swan.ulowell.edu>
  6. Date: 25 Oct 88 00:55:00 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 2059
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: dillon@cory.berkeley.edu (Matt Dillon)
  12. Posting-number: Volume 2, Issue 17
  13. Archive-name: util/dres.2
  14.  
  15. # This is a shell archive.  Remove anything before this line
  16. # then unpack it by saving it in a file and typing "sh file"
  17. # (Files unpacked will be owned by you and have default permissions).
  18. # This archive contains the following files:
  19. #    notinlib/graph.c
  20. #    notinlib/ioctl.c
  21. #    notinlib/muldiv.asm
  22. #    src/qint.asm
  23. #    src/ires.h
  24. #    src/lists.asm
  25. #    src/timedate.c
  26. #    src/oldfile.c
  27. #    src/oldfile.h
  28. #    src/res.c
  29. #
  30. if `test ! -d notinlib`
  31. then
  32.   mkdir notinlib
  33.   echo "mkdir notinlib"
  34. fi
  35. if `test ! -s notinlib/graph.c`
  36. then
  37. echo "writing notinlib/graph.c"
  38. cat > notinlib/graph.c << '\Rogue\Monster\'
  39.  
  40.  
  41. /*
  42.  *  GRAPH.C
  43.  */
  44.  
  45. #define GRAPH    struct _GRAPH
  46. #define GNODE    struct _GNODE
  47. #define GCTRL    struct _GCTRL
  48.  
  49. /*
  50.  *  Flags field:    The upper 4 bits are copied to the lower 4 bits after
  51.  *            the flags are processed, allowing for 'temporary'
  52.  *            conditions.
  53.  *
  54.  *  FL_SKIP        Propogate a skip condition.  As soon as the next node
  55.  *            is ready to begin processing, cause it not to run
  56.  *            its function and propogate the FL_SKIP to all of its
  57.  *            children, and all of their children, etc...
  58.  *
  59.  *  FL_SRC        Infinite source, this arc is always ready with the
  60.  *            given value.
  61.  */
  62.  
  63. GLINK {
  64.     MINNODE FNode;    /*  link from, list based at node    */
  65.     MINNODE TNode;    /*  link to, list based at node     */
  66.     GNODE   *FGNode;    /*  from this node            */
  67.     GNODE   *TGNode;    /*  to this node            */
  68.     long    FromId;    /*  Identify value slot for source    */
  69.     long    ToId;    /*  Identify value slot for destination */
  70.     long    Value;    /*  value to pass to 'to' node          */
  71.     ubyte   Ready;    /*  value pending, else no value pending*/
  72.     ubyte   Flags;    /*  FL_SKIP,FL_NULL,FL_SRC        */
  73.     ubyte   XFlags;    /*  XL_READ                */
  74.     ubyte   filler;
  75. };
  76.  
  77. GNODE {
  78.     MINNODE GNode;    /*  master list node            */
  79.     GRAPH   *Graph;    /*  owning graph            */
  80.     APTR    Func;    /*  Function                */
  81.     long    Arg;    /*  Argument                */
  82.     short   WaitCnt;    /*  # parents who are not ready     */
  83.     MINLIST ChildList;    /*  list of children            */
  84.     MINLIST ParentList; /*  list of parents            */
  85.     MINLIST WakeUpList; /*  WakeUp tasks waiting for an ARC to clear    */
  86. };
  87.  
  88. GRAPH {
  89.     MINLIST GNodes;    /*  list of all graphs in node    */
  90.     long    A45[2];    /*  global base registers    */
  91.     long    UsrLen;
  92. };
  93.  
  94. GRAPH *
  95. AllocGraph(usrdatalen)
  96. {
  97.     GRAPH *graph = AllocMem(sizeof(GRAPH), MEMF_PUBLIC|MEMF_CLEAR);
  98.     NewList(&graph->GNodes);
  99.     graph->a45[0] = A4;
  100.     graph->a45[1] = A5;
  101.     graph->UsrLen = usrdatalen;
  102. }
  103.  
  104. GNODE *
  105. AllocGraphNode(graph, func, arg, usrdata/NULL)
  106. GRAPH *graph;
  107. long arg;
  108. {
  109.     GNODE *gnode = AllocMem(sizeof(GNODE), MEMF_PUBLIC|MEMF_CLEAR);
  110.     AddTail(&graph->GNodes, &gnode->GNode);
  111.     gnode->Graph = graph;
  112.     gnode->Func  = func;
  113.     gnode->Arg     = arg;
  114.     NewList(&gnode->ChildList);
  115.     NewList(&gnode->ParentList);
  116.     NewList(&gnode->WakeUpList);
  117. }
  118.  
  119. /*
  120.  *  Remove all arcs and free a graph node
  121.  */
  122.  
  123. FreeGraphNode(gnode)
  124. GNODE *gnode;
  125. {
  126.     Forbid();
  127.     Remove(gnode);
  128.     while (glink = GetHead(&gnode->ChildList))
  129.     RemGraphArc(gnode, glink->FGTNode);
  130.     while (glink = GetHeadOff(&gnode->ParentList, 8))
  131.     RemGraphArc(glink->FGFNode, gnode);
  132.     Permit();
  133.     FreeMem(gnode, sizeof(GNODE));
  134. };
  135.  
  136. FreeGraph(graph)
  137. GRAPH *graph;
  138. {
  139.     Forbid();
  140.     while (gnode = GetHead(&graph->GNodes))
  141.     FreeGraphNode(gnode);
  142.     Permit();
  143.     FreeMem(graph, sizeof(GRAPH));
  144. }
  145.  
  146. /*
  147.  *  Set the user data for a given node.  The data is copied into an
  148.  *  equivalent buffer for the node.
  149.  */
  150.  
  151. SetUserData(gnode, usrdata/NULL)
  152. GNODE *gnode;
  153. {
  154. }
  155.  
  156. /*
  157.  *  Add a directed arc to the graph.  Set the arc to 'not ready' and
  158.  *  increment the child node's WaitCnt
  159.  */
  160.  
  161. AddGraphArc(from, to)
  162. GNODE *from, *to;
  163. {
  164.     GLINK *glink = AllocMem(sizeof(GLINK), MEMF_PUBLIC);
  165.  
  166.     Forbid();
  167.     AddTail(&from->ChildList, &glink->FNode);
  168.     AddTail(&to->ParentList, &glink->TNode);
  169.     glink->FGNode = from;
  170.     glink->FTNode = to;
  171.     ++to->WaitCnt;
  172.     Permit();
  173. }
  174.  
  175. chklink(glink, gnode)
  176. GLINK *glink;
  177. GNODE *gnode;
  178. {
  179.     if (glink->TGNode == gnode)
  180.     return(glink);
  181.     return(NULL);
  182. }
  183.  
  184. RemGraphArc(from, to)
  185. GNODE *from, *to;
  186. {
  187.     GLINK *glink;
  188.  
  189.     Forbid();
  190.     if (glink = SearchFwdNode(GetHead(&from->ChildList), chklink, 0, to)) {
  191.     Remove(&glink->FNode);
  192.     Remove(&glink->TNode);
  193.     if (!glink->Ready) {
  194.         if (--to->WaitCnt == 0 && GetHeadOff(&to->ParentList, 8))
  195.         GHandler(to);
  196.     }
  197.     }
  198.     Permit();
  199. }
  200.  
  201. SetGNodeFunc(gnode, func)
  202. GNODE *gnode;
  203. APTR func;
  204. {
  205.     gnode->Func = func;
  206. }
  207.  
  208. SetGNodeArg(gnode, arg)
  209. GNODE *gnode;
  210. {
  211.     gnode->Arg = arg;
  212. }
  213.  
  214. APTR
  215. GetGNodeFunc(gnode)
  216. GNODE *gnode;
  217. {
  218.     return(gnode->Func);
  219. }
  220.  
  221. long
  222. GetGNodeArg(gnode)
  223. GNODE *gnode;
  224. {
  225.     return(gnode->Arg);
  226. }
  227.  
  228. /*
  229.  *  This function may ONLY be called by a node function, and retrieves
  230.  *  the value from one of the parent arcs (arcs comming in).  When the
  231.  *  node function returns, any remaining unread parent arc's values will
  232.  *  be discarded.
  233.  */
  234.  
  235. long
  236. GetArcValue(ToId)
  237. {
  238.  
  239. }
  240.  
  241. /*
  242.  *  This function may ONLY be called by a node function, and sets the
  243.  *  result value to one of its child arcs (arcs going out).  When the
  244.  *  node function returns, any remaining unset child arc's values will
  245.  *  be SKIPd.
  246.  *
  247.  *  NOTE!  This function will block on child nodes which have yet to
  248.  *  read the previous value with GetArcValue() or are still running.
  249.  */
  250.  
  251. SetArcValue(gnode, FromId, flags)
  252. GNODE *gnode;
  253. {
  254. }
  255.  
  256. /*
  257.  *  This function may be called by anybody, and forces a value into an
  258.  *  arc.  This function is usually used to 'prime' a graph.
  259.  */
  260.  
  261. PrimeArc(from, to, value)
  262. GNODE *from, *to;
  263. {
  264. }
  265.  
  266. /*
  267.  *  GetGraph()
  268.  *
  269.  *  Load the two buffers with entries corrosponding to the graph.  arcen
  270.  *  and nodeen initially contain the number of ARC and NODE structure
  271.  *  entries that have been allocated.  These variables will hold the
  272.  *  actual number of ARC and NODE entries in the graph regardless of
  273.  *  whether the operation succeeds.
  274.  *
  275.  *  0 is returned if the operation does not succeed, 1 if it does.
  276.  *  The size of the node structure depends on the size of attached
  277.  *  user information.
  278.  *
  279.  *  ARC structure:  two words / entry, representing an arc (from, to),
  280.  *            where each word is an index (by entry #) into nodebuf.
  281.  *            i.e. 0, 1, 2 ... even if usrdatalen is 0.
  282.  *
  283.  *  NODE structure: any user data that has been applied to the node, as
  284.  *            specified by AllocGraphNode().
  285.  */
  286.  
  287. GetArcs(graph, arcbuf, &arcen, nodebuf, &nodeen)
  288. GRAPH *graph;
  289. {
  290.  
  291.  
  292. }
  293.  
  294. \Rogue\Monster\
  295. else
  296.   echo "will not over write notinlib/graph.c"
  297. fi
  298. if [ `wc -c notinlib/graph.c | awk '{printf $1}'` -ne 5849 ]
  299. then
  300. echo `wc -c notinlib/graph.c | awk '{print "Got " $1 ", Expected " 5849}'`
  301. fi
  302. if `test ! -s notinlib/ioctl.c`
  303. then
  304. echo "writing notinlib/ioctl.c"
  305. cat > notinlib/ioctl.c << '\Rogue\Monster\'
  306.  
  307. /*
  308.  *FUNC= IoCreate    D0/D1/A0
  309.  *FUNC= IoDelete    D0
  310.  *FUNC= IoOpen        D0/D1/A0
  311.  *FUNC= IoClose     A0
  312.  ;FUNC= IoCtl        D0/D1/D2/A0
  313.  *FUNC= NULL        -
  314.  *FUNC= NULL        -
  315.  *FUNC= NULL        -
  316.  *FUNC= NULL        -
  317.  *FUNC= NULL        -
  318.  *FUNC= NULL        -
  319.  *FUNC= NULL        -
  320.  */
  321.  
  322. #include <local/typedefs.h>
  323. #include <local/ioctl.h>
  324.  
  325. typedef long    (*FPTR)();
  326.  
  327. #define HAN struct _HAN
  328. #define MHAN struct _MHAN
  329.  
  330. #define HANSIZE     8
  331.  
  332. HAN {
  333.     long    Reserved;
  334.     MHAN    *MHan;        /*  Related MHandle        */
  335.             /*    USER STRUCTURE    */
  336. };
  337.  
  338. MHAN {
  339.     NODE    Node;
  340.     long    (*IoCtlFunc)();     /*  Control Function / NULL */
  341.     uword   Refs;        /*  Total References        */
  342.     uword   HanSize;        /*  Size of a HANdle        */
  343. };
  344.  
  345. #asm
  346.  
  347. MHA_IOCTLFUNC    equ    14
  348.  
  349. #endasm
  350.  
  351. static MLIST  MList = { (MNODE *)&MList.mlh_Tail, NULL, (MNODE *)&MList.mlh_Head };
  352. static long   Lock[2] = { 0,0 };
  353.  
  354. lIoCreate(name, func, hansize)
  355. char *name;
  356. long (*func)();
  357. {
  358.     register MHAN *mh;
  359.     long res = -1;
  360.  
  361.     hansize += HANSIZE;
  362.     LockAddr(Lock);
  363.     for (mh = GetHead(&MList); mh; mh = GetSucc(mh)) {
  364.     if (strcmp(name, mh->Node.ln_Name) == 0)
  365.         goto fail;
  366.     }
  367.     if ((mh = AllocMem(sizeof(MHAN), MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
  368.     goto fail;
  369.     if ((mh->Node.ln_Name = AllocMem(strlen(name)+1, MEMF_PUBLIC)) == NULL) {
  370.     FreeMem(mh, sizeof(MHAN));
  371.     goto fail;
  372.     }
  373.     strcpy(mh->Node.ln_Name, name);
  374.     mh->IoCtlFunc = func;
  375.     mh->HanSize = HANSIZE + hansize;
  376.     AddHead(&MList, mh);
  377.     fioctl(func, _IOC_CREATE, NULL, 0);
  378.     res = 0;
  379. fail:
  380.     UnLockAddr(Lock);
  381.     return(res);
  382. }
  383.  
  384. /*
  385.  *  Delete an IO device.  The device's name is removed from the nameslist
  386.  *  and any further non-internal IoCtl's on active connections will return
  387.  *  -1.
  388.  */
  389.  
  390. lIoDelete(name)
  391. char *name;
  392. {
  393.     register MHAN *mh;
  394.     long (*func)();
  395.  
  396.     LockAddr(Lock);
  397.     for (mh = GetHead(&MList); mh; mh = GetSucc(mh)) {
  398.     if (mh->Node.ln_Name && strcmp(name, mh->Node.ln_Name) == 0)
  399.         break;
  400.     }
  401.     if (!mh) {
  402.     UnLockAddr(mh);
  403.     return(-1);
  404.     }
  405.  
  406.     /*    Prevent further opens & flag for removal    */
  407.  
  408.     FreeMem(mh->Node.ln_Name, strlen(mh->Node.ln_Name)+1);
  409.     mh->Node.ln_Name = NULL;
  410.     func = mh->IoCtlFunc;
  411.     mh->IoCtlFunc = NULL;
  412.  
  413.     /*    Call _IOC_DELETE if no more references & delete */
  414.  
  415.     UnLockAddr(Lock);
  416.     fioctl(func, _IOC_DELETE, NULL, 0);
  417.  
  418.     if (mh->Refs == 0) {
  419.     Remove(mh);
  420.     FreeMem(mh, sizeof(MHAN));
  421.     return(0);
  422.     }
  423.     return(1);
  424. }
  425.  
  426. HAN *
  427. lIoOpen(name, arg1, arg2)
  428. char *name;
  429. ulong arg1, arg2;
  430. {
  431.     register MHAN *mh;
  432.     register HAN *han;
  433.  
  434.     LockAddr(Lock);
  435.     for (mh = GetHead(&MList); mh; mh = GetSucc(mh)) {
  436.     if (mh->Node.ln_Name && strcmp(name, mh->Node.ln_Name) == 0)
  437.         break;
  438.     }
  439.     if (!mh) {
  440.     UnLockAddr(Lock);
  441.     return(NULL);
  442.     }
  443.     if (!(han = AllocMem(mh->HanSize, MEMF_CLEAR|MEMF_PUBLIC))) {
  444.     UnLockAddr(Lock);
  445.     return(NULL);
  446.     }
  447.     ++mh->Refs;
  448.     UnLockAddr(Lock);
  449.     han->MHan = mh;
  450.     if (IoCtl(han, _IOC_OPEN, arg1, arg2) == -1) {
  451.     FreeMem(han, mh->HanSize);
  452.     LockAddr(Lock);
  453.     if (--mh->Refs == 0 && mh->Node.ln_Name == NULL) {
  454.         Remove(mh);
  455.         FreeMem(mh, sizeof(MHAN));
  456.     }
  457.     UnLockAddr(Lock);
  458.     return(NULL);
  459.     }
  460.     UnLockAddr(Lock);
  461.     return(han);
  462. }
  463.  
  464. lIoClose(han)
  465. register HAN *han;
  466. {
  467.     register MHAN *mh = han->MHan;
  468.     long hansize = mh->HanSize;
  469.  
  470.     IoCtl(han, _IOC_CLOSE, NULL, NULL);        /*  finishup    */
  471.     LockAddr(Lock);
  472.     if (--mh->Refs == 0 && mh->Node.ln_Name == NULL) {
  473.     Remove(mh);
  474.     FreeMem(mh, sizeof(MHAN));
  475.     }
  476.     UnLockAddr(Lock);
  477.     FreeMem(han, hansize);
  478.     return(0);
  479. }
  480.  
  481. #asm
  482.         ;    IoCtl(han:D0, cmd:D1, buf:D2, bytes:A0)
  483.         ;
  484.         ;    (1) Call IoctlFunc if it exists,    (*func)(han,cmd,buf,bytes)
  485.         ;    (2) else call internal function or if IoctlFunc returns -1
  486.  
  487.         public  _lIoCtl
  488.         public  _AutoFunc
  489.  
  490. _lIoCtl:
  491.         addq.l  #8,D0                ; skip handle header
  492.         movem.l D2/D3/A4/A5/A6,-(sp)            ; C compatibility
  493.         movem.l D0/D1/D2/A0,-(sp)               ; function call params
  494.         move.l  D0,A0
  495.         move.l  -4(A0),A0                       ; A0 = master handle
  496.         move.l  MHA_IOCTLFUNC(A0),A1            ; A1 = function to call
  497.         move.l  A1,D0                ; NULL function
  498.         beq     .iocn
  499.         jsr     (A1)
  500.         cmp.l   #-1,D0                ; result -1 ?
  501.         bne     .iocr
  502. .iocn        lea     _AutoFunc,A1            ; error, try internal func
  503.         jsr     (A1)
  504. .iocr        lea     16(sp),sp
  505.         movem.l (sp)+,D2/D3/A4/A5/A6
  506.         rts
  507.  
  508.         ;    fioctl(func, cmd, buf1, buf2) .. called as: (NULL,cmd,buf1,buf2)
  509.         ;    (i.e. handleless)
  510.  
  511. _fioctl:    movem.l 4(sp),D0/D1/A0/A1       ; get stack args
  512.         movem.l D2/D3/A4/A5/A6,-(sp)    ; save regs that might get trashed
  513.         move.l  D0,A6            ; function to call
  514.         moveq.l #0,D0            ; (usually is the handle)
  515.         movem.l D0/D1/A0/A1,-(sp)       ; push args
  516.         jsr     (A6)                    ; make call
  517.         lea     16(sp),sp               ; pop args
  518.         movem.l (sp)+,D2/D3/A4/A5/A6    ; restore regs
  519.         rts
  520.  
  521. #endasm
  522.  
  523. AutoFunc(han, cmd, arg1, arg2)
  524. register HAN *han;
  525. ulong cmd, arg1, arg2;
  526. {
  527.     han = (HAN *)((char *)han - 8);
  528.  
  529.     switch(cmd) {
  530.     case IOC_GETFUNC:
  531.     return ((long)han->MHan->IoCtlFunc);
  532.     case IOC_SETFUNC:
  533.     han->MHan->IoCtlFunc = (FPTR)arg1;
  534.     return(0);
  535.     case IOC_DEVCLAS:
  536.     return(0);
  537.     case IOC_DUP:
  538.     {
  539.         register long hansize = han->MHan->HanSize;
  540.         register HAN *new = AllocMem(hansize, MEMF_PUBLIC);
  541.         register long res;
  542.         if (new) {
  543.         BMov(han, new, hansize);
  544.         res = IoCtl(new, _IOC_DUP, arg1, arg2);
  545.         if (res != -1)
  546.             return((long)new);
  547.         FreeMem(new, hansize);
  548.         }
  549.     }
  550.     break;
  551.     }
  552.     return(-1);
  553. }
  554.  
  555. \Rogue\Monster\
  556. else
  557.   echo "will not over write notinlib/ioctl.c"
  558. fi
  559. if [ `wc -c notinlib/ioctl.c | awk '{printf $1}'` -ne 5581 ]
  560. then
  561. echo `wc -c notinlib/ioctl.c | awk '{print "Got " $1 ", Expected " 5581}'`
  562. fi
  563. if `test ! -s notinlib/muldiv.asm`
  564. then
  565. echo "writing notinlib/muldiv.asm"
  566. cat > notinlib/muldiv.asm << '\Rogue\Monster\'
  567.  
  568. ;FUNC=    MulDiv        D0/D1/D2
  569. ;FUNC=    UMulDiv     D0/D1/D2
  570. ;FUNC=    MulShift    D0/D1/D2
  571. ;FUNC=    UMulShift   D0/D1/D2
  572.  
  573.         ;    MulDiv    (a ,b ,c)   32x32->64 64/32->32     (signed)
  574.         ;    MulShift(a ,b ,n)   32x32->64 64>>n->32     (signed)
  575.         ;         D0,D1,D2
  576.         ;
  577.         ;    32x32->64 64/32->32
  578.         ;    32x32->64 64>>n->32
  579.         ;
  580.         ;    note:    n is a word
  581.  
  582.         public  _MulDiv
  583.         public  _UMulDiv
  584.         public  _MulShift
  585.         public  _UMulShift
  586.  
  587.         ;    Various connotations specifying which arguments are
  588.         ;    unsigned (you gain a bit when using unsigned arguments)
  589.  
  590. REGS        eqr     D2-D7
  591.  
  592. _UMulDiv    movem.l REGS,-(sp)
  593.         clr.w   D7
  594.         bra     .md10
  595. _MulDiv     movem.l REGS,-(sp)
  596.         clr.w   D7
  597.         tst.l   D0
  598.         bpl     .md2
  599.         neg.l   D0
  600.         tst.l   D1        ; neg
  601.         bpl     .md1    ; neg
  602.         neg.l   D1
  603.         tst.l   D2        ; neg neg
  604.         bpl     .md10   ; neg neg
  605.         neg.l   D2
  606.         bra     .md9    ; neg neg neg
  607. .md1        tst.l   D2        ; neg
  608.         bpl     .md9    ; neg
  609.         neg.l   D2
  610.         bra     .md10   ; neg neg
  611. .md2        tst.l   D1
  612.         bpl     .md3
  613.         neg.l   D1
  614.         tst.l   D2        ; neg
  615.         bpl     .md9    ; neg
  616.         neg.l   D2
  617.         bra     .md10   ; neg neg
  618. .md3        tst.l   D2
  619.         bpl     .md10
  620.         neg.l   D2
  621.         bra     .md9
  622.  
  623. _UMulShift  movem.l REGS,-(sp)
  624.         clr.w   D7
  625.         bra     .md6
  626. _MulShift   movem.l REGS,-(sp)
  627.         clr.w   D7
  628.         tst.l   D0
  629.         bpl     .md4
  630.         neg.l   D0
  631.         tst.l   D1
  632.         bpl     .md5
  633.         neg.l   D0
  634.         bra     .md6
  635. .md4        tst.l   D1
  636.         bpl     .md6
  637.         neg.l   D1
  638. .md5        addq.w  #1,D7
  639.  
  640. .md6        swap    D0
  641.         swap    D1
  642.         tst.w   D0
  643.         beq     .md601
  644.         bsr     .md0huge
  645.         beq     .md602a
  646.         bra     .md603
  647. .md601        tst.w   D1
  648.         beq     .md602
  649.         bsr     .md1huge
  650.         beq     .md602a
  651.         bra     .md603
  652. .md602        swap    D0
  653.         swap    D1
  654.         mulu    D1,D0
  655. .md602a     lsr.l   D2,D0
  656.         bra     .mddone
  657. .md603        subq.w  #1,D2
  658.         bmi     .mddone
  659. .md604        lsr.l   #1,D3
  660.         roxr.l  #1,D0
  661.         dbf     D2,.md604
  662.         bra     .mddone
  663.  
  664.  
  665. .md10        swap    D0
  666.         swap    D1
  667.         tst.w   D0
  668.         beq     .md101
  669.         bsr     .md0huge
  670.         beq     .mdsdiv
  671.         bsr     div64
  672.         bra     .mddone
  673. .md101        tst.w   D1
  674.         beq     .md105
  675.         bsr     .md1huge
  676.         beq     .mdsdiv
  677.         bsr     div64
  678.         bra     .mddone
  679. .md105        swap    D0        ; both word sized
  680.         swap    D1
  681.         mulu    D1,D0    ; D1.WxD0.W -> D0.L
  682. .mdsdiv     move.l  D2,D1
  683.         jsr     .divu#
  684.  
  685.         ;
  686.         ;
  687.  
  688. .md9        addq.w  #1,D7
  689.  
  690.         ;    All elements now unsigned, D7.W determines whether to
  691.         ;    negate at end.
  692.  
  693. .mddone     btst.l  #0,D7
  694.         beq     .mddone2
  695.         neg.l   D0
  696. .mddone2    movem.l (sp)+,REGS
  697.         rts
  698.  
  699.  
  700.         ;    NOTE:    entered with register halves reversed
  701.         ;
  702.         ;    D2 not effected
  703.         ;    Test D3 on return
  704.  
  705. .md0huge    tst.w   D1
  706.         beq     .md1hugex    ; D0.L, D1.W
  707.                 ; D0.L, D1.L    (long x long)
  708.         move.w  D0,D4    ; save ah
  709.         move.w  D0,D3    ; ah bh
  710.         mulu.w  D1,D3
  711.         swap    D0        ; al bh
  712.         move.w  D0,D5
  713.         mulu.w  D1,D5
  714.         swap    D1
  715.         mulu.w  D1,D0    ; al bl
  716.         mulu.w  D4,D1    ; ah bl
  717.         add.l   D1,D5    ; combine blah and bhal
  718.         bcc     .mud1
  719.         add.l   #$10000,D3
  720. .mud1        swap    D0        ; LSB MSB
  721.         add.w   D5,D0
  722.         swap    D0
  723.         clr.w   D5
  724.         swap    D5
  725.         addx.l  D5,D3    ;64 bit mul result: D3|D0
  726.         rts         ;Test D3
  727.  
  728.         ; D2 not effected
  729.  
  730. .md1huge    exg     D0,D1
  731. .md1hugex
  732.         ; D0.L, D1.W    al ah
  733.         ;               bl
  734.  
  735.         move.w  D0,D3
  736.         mulu.w  D1,D3    ; D3 = bl x ah
  737.         swap    D0
  738.         mulu.w  D1,D0    ; D0 = bl x al
  739.         swap    D0        ; add lsb byte of D3 to msb byte of D0
  740.         add.w   D3,D0
  741.         swap    D0
  742.         clr.w   D3        ; doesn't effect X
  743.         swap    D3        ; msb of D3 actually lsb of second longword
  744.         moveq.l #0,D1
  745.         addx    D1,D3    ; possible x(carry) from previous addition
  746.                 ; 64 bit mul result: D3|D0
  747.                 ; Test D3
  748.         rts
  749.  
  750.         ;    DIV64
  751.         ;
  752.         ;    64/32->32   D3|D0 / D2 -> D0
  753.  
  754. div64:
  755.         move.l  #0,A0    ;Divide!    D1 into D3|D0, D2 = cntr, A0 = rslt
  756.         move.w  #31,D2    ;(no initial compare).  31 + 1 iterations
  757. .mud10        adda.l  A0,A0    ;shift result left
  758.         asl.l   #1,D0    ;Shift left
  759.         roxl.l  #1,D3
  760.         cmp.l   D1,D3
  761.         blo     .mud11    ;if D3    < D1, skip
  762.         sub.l   D1,D3    ;   D3 >= D1
  763.         addq.l  #1,A0    ;result = result | 1
  764. .mud11        dbf     D2,.mud10
  765.  
  766.         ;    If remainder (D3) larger than 1/2 C (D1 >> 1), then
  767.         ;    round up result.
  768.  
  769.         lsr.l   #1,D1
  770.         cmp.l   D1,D3
  771.         blo     .mud12    ; skip if remainder < 1/2C
  772.         addq.l  #1,A0
  773. .mud12
  774.         move.l  A0,D0    ;return result
  775.         rts
  776.  
  777. \Rogue\Monster\
  778. else
  779.   echo "will not over write notinlib/muldiv.asm"
  780. fi
  781. if [ `wc -c notinlib/muldiv.asm | awk '{printf $1}'` -ne 4567 ]
  782. then
  783. echo `wc -c notinlib/muldiv.asm | awk '{print "Got " $1 ", Expected " 4567}'`
  784. fi
  785. if `test ! -d src`
  786. then
  787.   mkdir src
  788.   echo "mkdir src"
  789. fi
  790. if `test ! -s src/qint.asm`
  791. then
  792. echo "writing src/qint.asm"
  793. cat > src/qint.asm << '\Rogue\Monster\'
  794.  
  795. ;   QINT.ASM
  796. ;
  797. ;   handle= OpenQInts()
  798. ;        CloseQInts(handle:A0)
  799. ;        SetQPri(handle:D0, pri:D1)
  800. ;        SetQVector(handle:D0, vector:D1, signo:D2, arg:D3, pri:A0)
  801.  
  802.         public    _lOpenQInts
  803.         public    _lCloseQInts
  804.         public    _lSetQPri
  805.         public    _lSetQVector
  806.  
  807.         public    _LVOFindTask
  808.         public    _LVOAllocMem
  809.         public    _LVOFreeMem
  810.         public    _LVOForbid
  811.         public    _LVOPermit
  812.         public    _LVODisable
  813.         public    _LVOEnable
  814.         public    _LVOEnqueue
  815.         public    _LVORemove
  816.         public    _LVOSetSignal
  817.         public    _LVOSetExcept
  818.  
  819. QINT_SIZE    EQU    32
  820.  
  821. QINT_NODE    EQU    0
  822. QINT_VECTOR    EQU    14
  823. QINT_SIGMASK    EQU    18
  824. QINT_ARG    EQU    22
  825. QINT_UNUSED    EQU    26
  826.  
  827. HAN_SIZE    EQU    36+32*QINT_SIZE
  828. HAN_A4        EQU    0
  829. HAN_A5        EQU    4
  830. HAN_EXCODE    EQU    8
  831. HAN_EXDATA    EQU    12
  832. HAN_INTS    EQU    16
  833. HAN_INHAN    EQU    18
  834. HAN_PRI     EQU    20
  835. HAN_LIST    EQU    22
  836. HAN_QINT    EQU    36
  837.  
  838. MEMF_CLEAR    EQU    $10000
  839. MEMF_PUBLIC    EQU    $1
  840.  
  841. LH_HEAD     EQU    0
  842. LH_TAIL     EQU    4
  843. LH_TAILPRED    EQU    8
  844.  
  845. LN_TYPE     EQU    8
  846. LN_PRI        EQU    9
  847.  
  848. TC_EXCEPTCODE    EQU    42
  849. TC_EXCEPTDATA    EQU    38
  850.  
  851.  
  852. _lOpenQInts:
  853.         movem.l D2/D3/A2/A6,-(sp)
  854.         move.l  4,A6
  855.         move.l  #HAN_SIZE,D0
  856.         move.l  #MEMF_CLEAR|MEMF_PUBLIC,D1
  857.         jsr     _LVOAllocMem(A6)
  858.         tst.l   D0
  859.         beq     .oqi1
  860.         move.l  D0,A2
  861.         move.b  #-128,HAN_PRI(A2)
  862.         movem.l A4/A5,HAN_A4(A2)
  863.         lea.l   HAN_LIST+LH_HEAD(A2),A0
  864.         lea.l   HAN_LIST+LH_TAIL(A2),A1
  865.         move.l  A1,(A0)
  866.         move.l  A0,LH_TAILPRED(A0)
  867. .oqi1        movem.l (sp)+,D2/D3/A2/A6
  868.         rts
  869.  
  870. _lCloseQInts:                 ; A0 = handle
  871.         movem.l D2/D3/A2/A6,-(sp)
  872.         move.l  4,A6
  873.         move.l  A0,A2        ; A2 = handle
  874.         move.l  A0,D0        ; skip if null
  875.         beq     .cqi1
  876.         moveq.l #31,D3        ; D3 = sig number.
  877. .cqi2        move.w  D3,-(sp)
  878.         move.l  D3,D2        ; SetQVector(han, NULL, sig#, 0, 0)
  879.         move.l  A2,D0        ;         D0   D1    D2     D3  A0
  880.         moveq.l #0,D1
  881.         move.l  D1,D3
  882.         move.l  D1,A0
  883.         jsr     _lSetQVector
  884.         move.w  (sp)+,D3
  885.         dbf     D3,.cqi2
  886.  
  887. .cqi1        movem.l (sp)+,D2/D3/A2/A6
  888.         rts
  889.  
  890.  
  891.  
  892.         ;    _EXCEPT ,  Exception handler.
  893.         ;
  894.         ;entry:
  895.         ;    D0 = exceptions that occured
  896.         ;    A1 = Handle
  897.         ;
  898.         ;auto:
  899.         ;    A2    = Handle
  900.         ;    A4/A5    = Possible Global Base Registers
  901.         ;    D4    = Bit# count
  902.         ;    D6    = Exceptions that occured
  903.  
  904.  
  905. _except:
  906.         move.l    4,A6        ;A6 = Exec Base
  907.         move.l    D0,D6        ;D6 = Exception Bit Mask
  908.         movem.l    HAN_A4(A1),A4/A5;get global base register(s).
  909.         move.l    A1,A2        ;A2 = HANDLE BASE
  910.  
  911.         ;    Queue any exceptions which are interrupts.  Exceptions
  912.         ;    for interrupts which are queued are NOT reenabled until
  913.         ;    they are actually run.
  914.         ;
  915.         ;    Note that in the loop we must loop to .ex2 to decrement
  916.         ;    D4, which doesn't occur when we find a '1'.  The Z bit
  917.         ;    must be set when we loop to .ex2
  918.  
  919. .ex0        moveq.l    #31,D4        ;D4 = BIT NUMBER
  920. .ex1        btst.l    D4,D6        ; test bits
  921. .ex2        dbne    D4,.ex1     ; until found a '1'
  922.         beq     .ex10        ;or loop exhausted (D4 == -1)
  923.  
  924.         move.l    D4,D5        ;Calculate address of QINT.
  925.         asl.l    #5,D5        ;D5 = index * sizeof(QINT)
  926.         pea.l    HAN_QINT(A2)
  927.         add.l    (sp)+,D5        ;     + Base of QINT array
  928.         move.l    D5,A3        ;A3 = QINT address
  929.         tst.l    QINT_VECTOR(A3) ;Is this exception vectored?
  930.         beq     .ex2        ;no, somebody else owns it
  931.  
  932. .ex3        bclr.l    D4,D6        ;clear exception bit.
  933.         jsr     _LVOForbid(A6)  ;Important operation!
  934.         move.l    A3,A1        ;A1 = node
  935.         lea.l    HAN_LIST(A2),A0 ;A0 = List Base
  936.         move.b    #5,LN_TYPE(A1)  ;mark node as being queued
  937.         jsr     _LVOEnqueue(A6)
  938.         jsr     _LVOPermit(A6)  ;enable exceptions
  939.         clr.w    D7        ;Force Z cc set.
  940.         bra     .ex2        ;loop (force decrement/loop)
  941.  
  942.         ;    Call the handler.  The handler is allowed to trash
  943.         ;    everything except D6/A7.  Called with A2 = Handle,
  944.         ;    A6 = Exec Base
  945.  
  946. .ex10        tst.w    HAN_INHAN(A2)   ;no need to call handler?
  947.         bne     .ex11
  948.         bsr     _handler    ;call handler
  949. .ex11        move.l    D6,D0        ;D0 = exception mask
  950.         beq     .ex12        ;we processed all exceptions
  951.         move.l    HAN_EXCODE(A2),A0 ;somebody else owns some exceptions
  952.         move.l    HAN_EXDATA(A2),A1 ;restore exception data pointer
  953.         jmp     (A0)            ;call him with remaining exceptions.
  954. .ex12        rts
  955.  
  956.         ;entry:
  957.         ;    A2    = Handle
  958.         ;    A4/A5    = Possible Global Base Registers
  959.         ;    A6    = EXEC base
  960.         ;
  961.         ;auto:
  962.         ;    A2    = Handle;
  963.         ;    A3    = Qint
  964.         ;    A4/A5    = GBRs
  965.         ;    A6    = EXEC base
  966.         ;    D4    = savepri
  967.  
  968. _handler:
  969.         move.b    #1,HAN_INHAN(A2)
  970.         jsr     _LVOForbid(A6)
  971. .hloop        move.l    HAN_LIST+LH_HEAD(A2),A3
  972.         lea.l    HAN_LIST+LH_TAIL(A2),A0
  973.         cmp.l    A0,A3            ;List is empty
  974.         beq     .hbreak
  975.         move.b    HAN_PRI(A2),D4          ;Check priority of node
  976.         cmp.b    QINT_NODE+LN_PRI(A3),D4
  977.         bgt     .hbreak         ;savepri > qintpri
  978.         move.l    A3,A1            ;A1 = node to remove
  979.         jsr     _LVORemove(A6)
  980.         move.b    #0,QINT_NODE+LN_TYPE(A3)
  981.         move.b    QINT_NODE+LN_PRI(A3),HAN_PRI(A2)
  982.         jsr     _LVOPermit(A6)
  983.         move.l    QINT_ARG(A3),-(sp)
  984.         move.l    QINT_VECTOR(A3),A0
  985.         jsr     (A0)
  986.         move.l    4,A6
  987.         addq.l    #4,sp
  988.         move.b    D4,HAN_PRI(A2)
  989.         tst.l    QINT_VECTOR(A3)         ;Reenable the exception
  990.         beq     .h1            ;only if the vector still
  991.         move.l    QINT_SIGMASK(A3),D0     ;exists.
  992.         move.l    D0,D1
  993.         jsr     _LVOSetExcept(A6)
  994. .h1        jsr     _LVOForbid(A6)
  995.         bra     .hloop
  996.  
  997. .hbreak     moveq.l    #0,D2
  998.         move.b    D2,HAN_INHAN(A2)
  999.         jsr     _LVOPermit(A6)
  1000.         move.l    D2,D0
  1001.         move.l    D2,D1
  1002.         jsr     _LVOSetExcept(A6)
  1003.         rts
  1004.  
  1005.         ;    SetQVector()
  1006.         ;
  1007.         ;    D0 = handle (copy to A2)
  1008.         ;    D1 = vector (copy to A3)
  1009.         ;    D2 = signo
  1010.         ;    D3 = arg    (copy to D5)
  1011.         ;    A0 = pri
  1012.         ;
  1013.         ;    A2 = handle
  1014.         ;    A3 = vector
  1015.         ;    A4 = qint
  1016.         ;    A5 = task
  1017.         ;
  1018.         ;    D2 = pri
  1019.         ;    D3 = sigmask
  1020.         ;    D4 = oldvector
  1021.         ;    D5 = arg
  1022.         ;    D6 =
  1023.         ;    D7 =
  1024.  
  1025. _lSetQVector:
  1026.         movem.l D2-D7/A2-A6,-(sp)
  1027.         move.l  4,A6
  1028.         move.l  D0,A2        ;   A2 = Handle
  1029.         move.l  D1,A3        ;   A3 = Vector
  1030.         move.l  D3,D5        ;   D5 =
  1031.  
  1032.         moveq.l #0,D3        ;   D3 = signal mask
  1033.         bset.l  D2,D3        ;   D2 = signal
  1034.         asl.l   #5,D2        ;   A4 = qint (han->QInt + signo)
  1035.         add.l   #HAN_QINT,D2
  1036.         add.l   A2,D2
  1037.         move.l  D2,A4        ;   A4 = QINT
  1038.         move.l  A0,D2        ;   D2 = priority
  1039.         move.w  #0,A1        ;   A5 = task
  1040.         jsr     _LVOFindTask(A6)
  1041.         move.l  D0,A5
  1042.  
  1043.         jsr     _LVOForbid(A6)      ;   Forbid
  1044.         move.l  QINT_VECTOR(A4),D4  ;   D4 = oldvector
  1045.         move.l  A3,D0
  1046.         bne     .sq100
  1047.  
  1048.         ;    If new vector is NULL, remove old vector if it exists.
  1049.  
  1050.         tst.l   D4
  1051.         beq     .sqdone
  1052.         moveq.l #0,D0
  1053.         move.l  D3,D1
  1054.         jsr     _LVOSetExcept(A6)
  1055.         cmp.b   #5,QINT_NODE+LN_TYPE(A4)
  1056.         bne     .sq1
  1057.         move.l  A4,A1
  1058.         jsr     _LVORemove(A6)
  1059.         move.b  #0,QINT_NODE+LN_TYPE(A4)
  1060. .sq1        sub.w   #1,HAN_INTS(A2)
  1061.         bne     .sq2
  1062.         jsr     _LVODisable(A6)
  1063.         move.l  HAN_EXCODE(A2),TC_EXCEPTCODE(A5)
  1064.         move.l  HAN_EXDATA(A2),TC_EXCEPTDATA(A5)
  1065.         jsr     _LVOEnable(A6)
  1066. .sq2        bra     .sqdone
  1067.  
  1068.         ;    If new vector not null, replace (possibly NULL) old vector
  1069.  
  1070. .sq100        tst.l   D4
  1071.         bne     .sq150
  1072.         add.w   #1,HAN_INTS(A2)     ; oldvector is null, setup task
  1073.         cmp.w   #1,HAN_INTS(A2)
  1074.         bne     .sq150
  1075.         jsr     _LVODisable(A6)
  1076.         move.l  TC_EXCEPTCODE(A5),HAN_EXCODE(A2)
  1077.         move.l  TC_EXCEPTDATA(A5),HAN_EXDATA(A2)
  1078.         move.l  #_except,TC_EXCEPTCODE(A5)
  1079.         move.l  A2,TC_EXCEPTDATA(A5)
  1080.         jsr     _LVOEnable(A6)
  1081.  
  1082. .sq150        move.l  D5,QINT_ARG(A4)
  1083.         move.b  D2,QINT_NODE+LN_PRI(A4)
  1084.         move.l  D3,QINT_SIGMASK(A4)
  1085.         move.l  D3,D0
  1086.         move.l  D3,D1
  1087.         jsr     _LVOSetExcept(A6)
  1088.         bra     .sqdone
  1089.  
  1090. .sqdone     move.l  A3,QINT_VECTOR(A4)
  1091.         jsr     _LVOPermit(A6)
  1092.         moveq.l #0,D0
  1093.         move.l  D0,D1
  1094.         jsr     _LVOSetExcept(A6)
  1095.         move.l  D4,D0
  1096.         movem.l (sp)+,D2-D7/A2-A6
  1097.         rts
  1098.  
  1099.         ;    SetQPri
  1100.         ;
  1101.         ;    D0 = handle
  1102.         ;    D1 = newpri
  1103.         ;
  1104.         ;    A2 = handle
  1105.         ;    D2 = newpri
  1106.         ;    D3 = oldpri
  1107. _lSetQPri:
  1108.         movem.l D2/D3/A2/A6,-(sp)
  1109.         move.l  4,A6
  1110.         move.l  D0,A2
  1111.         move.l  D1,D2
  1112.         jsr     _LVODisable(A6)
  1113.         move.b  HAN_PRI(A2),D3
  1114.         move.b  D2,HAN_PRI(A2)
  1115.         jsr     _LVOEnable(A6)
  1116.         cmp.b   D2,D3
  1117.         ble     .sqpdone            ; D3 <= D2 (old <= new)
  1118.         lea.l   HAN_LIST+LH_TAIL(A2),A0
  1119.         cmp.l   HAN_LIST+LH_HEAD(A2),A0
  1120.         beq     .sqpdone
  1121.  
  1122.         movem.l D4/A3,-(sp)
  1123.         jsr     _handler            ;A2 = handle, A6 = execbase
  1124.         movem.l (sp)+,D4/A3
  1125. .sqpdone:
  1126.         moveq.l #0,D0
  1127.         move.b  D3,D0
  1128.         movem.l (sp)+,D2/D3/A2/A6
  1129.         rts
  1130.  
  1131. \Rogue\Monster\
  1132. else
  1133.   echo "will not over write src/qint.asm"
  1134. fi
  1135. if [ `wc -c src/qint.asm | awk '{printf $1}'` -ne 8366 ]
  1136. then
  1137. echo `wc -c src/qint.asm | awk '{print "Got " $1 ", Expected " 8366}'`
  1138. fi
  1139. if `test ! -s src/ires.h`
  1140. then
  1141. echo "writing src/ires.h"
  1142. cat > src/ires.h << '\Rogue\Monster\'
  1143.  
  1144. /*
  1145.  *  Internal Resource Header Files
  1146.  */
  1147.  
  1148. #define TML    struct _TML
  1149. #define TREN    struct _TREN
  1150. #define SVS    struct _SVS
  1151. #define RFILE    struct _RFILE
  1152. #define FTABLE    struct _FTABLE
  1153. #define HTABLE    struct _HTABLE
  1154.  
  1155. /*
  1156.  *  Task Mem-List Resource structure
  1157.  */
  1158.  
  1159. TML {
  1160.     long    XLock[2];
  1161.     MLIST   RENList;    /*  List of resources            */
  1162.     MLIST   RFList;    /*  List of private resource Files  */
  1163. };
  1164.  
  1165. /*
  1166.  *  Task Resource Entry
  1167.  */
  1168.  
  1169. TREN {
  1170.     MNODE   Node;
  1171.     APTR    Ptr;
  1172.     long    (*Func)();
  1173. };
  1174.  
  1175. /*
  1176.  *  Swap Volume Structure
  1177.  */
  1178.  
  1179. SVS {
  1180.     MNODE   Node;
  1181.     long    XLock[2];
  1182.     long    Fh;     /*  associated fh or lock    */
  1183.     uword   Flags;    /*  HAVHANDLE, HAVLOCK        */
  1184.     long    Swapped;    /*  bytes swapped        */
  1185.     long    FileSize;    /*  current file size        */
  1186.     long    Free;    /*  bytes free            */
  1187.     long    Link[32];    /*  swap area free lists    */
  1188.     char    *Name;    /*  swap volume name        */
  1189. };
  1190.  
  1191. /*
  1192.  *  Resource File Structure
  1193.  */
  1194.  
  1195. RFILE {
  1196.     MNODE   Node;
  1197.     long    XLock[2];
  1198.     long    Fh;     /*  associated fh or lock    */
  1199.     long    HTsize;    /*  hash table size in file    */
  1200.     long    Loaded;    /*  bytes loaded        */
  1201.     long    Swapped;    /*  bytes swapped        */
  1202.     uword   Flags;    /*  HAVHANDLE, HAVLOCK        */
  1203.     uword   HTSize;    /*  pwr of 2, # of entries    */
  1204.     FTABLE  **HTab;    /*  [n]&3:0-mem 1-seek.  file access dict.  */
  1205.     HTABLE  **LTab;    /*  active resource access table (by name)  */
  1206.     char    *Name;    /*  resource file name        */
  1207. };
  1208.  
  1209. /*
  1210.  *  Hash table entry for dictionary
  1211.  */
  1212.  
  1213. FTABLE {
  1214.     long    Next;    /*  Next entry 0-end, &3:0-mem 1-seek        */
  1215.     uword   Flags;    /*  all applicable flags, inc load state    */
  1216.     ubyte   NLen;    /*  name length                 */
  1217.     ubyte   TLen;    /*  type length                 */
  1218.     long    Seek;    /*  seek position in file            */
  1219.     long    Len;    /*  size of resource in file / htable ptr   */
  1220.     ubyte   Name[2];    /*  extend structure to [n]            */
  1221. };
  1222.  
  1223. /*
  1224.  *  Hash table entry for active resource
  1225.  */
  1226.  
  1227. HTABLE {
  1228.     long    Next;    /*  Next entry 0-end, &3:0-mem 1-swapped    */
  1229.     uword   Flags;    /*  all applicable flags, inc load state    */
  1230.     uword   Refs;
  1231.     long    Ptr;    /*  data ptr, swap ptr                */
  1232.     long    Func;    /*  control function                */
  1233. };
  1234.  
  1235. \Rogue\Monster\
  1236. else
  1237.   echo "will not over write src/ires.h"
  1238. fi
  1239. if [ `wc -c src/ires.h | awk '{printf $1}'` -ne 2194 ]
  1240. then
  1241. echo `wc -c src/ires.h | awk '{print "Got " $1 ", Expected " 2194}'`
  1242. fi
  1243. if `test ! -s src/lists.asm`
  1244. then
  1245. echo "writing src/lists.asm"
  1246. cat > src/lists.asm << '\Rogue\Monster\'
  1247.  
  1248.         ;   EXTENDED LIST/NODE HANDLING
  1249.         ;
  1250.         ;   (C)CopyRight May 1988, Matthew Dillon, All Rights Reserved
  1251.         ;
  1252.  
  1253.  
  1254.         ;NOTE:    These routines accomodate structures where the
  1255.         ;    NODE used to traverse the list is not necessarily
  1256.         ;    at the beginning of the structure.  This, 'sptr'
  1257.         ;    refers to the structure pointer (not the node
  1258.         ;    pointer, unless the node is at the beginning), and
  1259.         ;    'off' offset refers to the offset into the structure
  1260.         ;    where the NODE resides.
  1261.  
  1262.         public    _lGetHead         ; node = GetHead(list)
  1263.         public    _lGetTail         ; node = GetTail(list)
  1264.         public    _lGetSucc         ; node = GetSucc(node)
  1265.         public    _lGetPred         ; node = GetPred(node)
  1266.         public    _lGetHeadOff         ; sptr = GetHeadOff(list, off)
  1267.         public    _lGetTailOff         ; sptr = GetTailOff(list, off)
  1268.         public    _lGetSuccOff         ; sptr = GetSuccOff(sptr, off)
  1269.         public    _lGetPredOff         ; sptr = GetPredOff(sptr, off)
  1270.         public    _lEnqueueLong         ; (void)EnqueueLong(list, start, sptr, valoff)
  1271.         public    _lEnqueueOffLong     ; (void)EnqueueOffLong(list, start, sptr, off, valoff)
  1272.         public    _lSearchFwdNode      ; ret  = SearchFwdNode(sptr, func, arg)      ->  func(somesptr,arg)
  1273.         public    _lSearchRvsNode      ; ret  = SearchRvsNode(sptr, func, arg)             (ditto)
  1274.         public    _lSearchFwdList      ; ret  = SearchFwdList(list, func, arg)             (ditto)
  1275.         public    _lSearchRvsList      ; ret  = SearchRvsList(list, func, arg)             (ditto)
  1276.         public    _lSearchFwdNodeOff   ; ret  = SearchFwdNode(sptr, func, off, arg) ->  func(somesptr,arg)
  1277.         public    _lSearchRvsNodeOff   ; ret  = SearchRvsNode(sptr, func, off, arg)        (ditto)
  1278.         public    _lSearchFwdListOff   ; ret  = SearchFwdList(list, func, off, arg)        (ditto)
  1279.         public    _lSearchRvsListOff   ; ret  = SearchRvsList(list, func, off, arg)        (ditto)
  1280.  
  1281.         ;   GETHEAD(list:A0)
  1282.         ;   GETSUCC(node:A0)
  1283. _lGetSucc:
  1284. _lGetHead:    move.l    (A0),A0
  1285.         tst.l    (A0)
  1286.         beq    .gh0
  1287.         move.l    A0,D0
  1288.         rts
  1289.  
  1290.         ;   GETTAIL(list:A0)
  1291.  
  1292. _lGetTail:    move.l    8(A0),A0
  1293.         tst.l    4(A0)
  1294.         beq    .gh0
  1295.         move.l    A0,D0
  1296.         rts
  1297.  
  1298.         ;   GETPRED(node:A0)
  1299.  
  1300. _lGetPred:    move.l    4(A0),A0
  1301.         tst.l    4(A0)
  1302.         beq    .gh0
  1303.         move.l    A0,D0
  1304.         rts
  1305.  
  1306. .gh0        moveq.l #0,D0
  1307.         rts
  1308.  
  1309.         ;   GETHEADOFF(list:D0, offset:D1)
  1310.  
  1311. _lGetHeadOff:    move.l    D0,A0
  1312.         move.l    (A0),A0
  1313.         tst.l    (A0)
  1314.         beq    .gh0
  1315.         sub.l    D1,A0
  1316.         move.l    A0,D0
  1317.         rts
  1318.  
  1319.         ;   GETTAILOFF(list:D0, offset:D1)
  1320.  
  1321. _lGetTailOff:    move.l    D0,A0
  1322.         move.l    8(A0),A0
  1323.         tst.l    4(A0)
  1324.         beq    .gh0
  1325.         sub.l    D1,A0
  1326.         move.l    A0,D0
  1327.         rts
  1328.  
  1329.         ;   SPTR is a structure pointer, where the node is offset
  1330.         ;   OFFSET from the base of the structure.
  1331.  
  1332.         ;   GETSUCCOFF(sptr:D0, offset:D1)
  1333.  
  1334. _lGetSuccOff:    move.l    D0,A0
  1335.         move.l    (A0,D1.L),A0
  1336.         tst.l    (A0)
  1337.         beq    .gh0
  1338.         suba.l    D1,A0
  1339.         move.l    A0,D0
  1340.         rts
  1341.  
  1342.         ;   GETPREDOFF(sptr:D0, offset:D1)
  1343.  
  1344. _lGetPredOff:    move.l    D0,A0
  1345.         move.l    4(A0,D1.L),A0
  1346.         tst.l    4(A0)
  1347.         beq    .gh0
  1348.         suba.l    D1,A0
  1349.         move.l    A0,D0
  1350.         rts
  1351.  
  1352.         ;   ENQUEUELONG(list:D0, start:D1, sptr:D2, valoff:D4)
  1353.         ;   ENQUEUEOFFLONG(list:D0, start:D1, sptr:D2, off:D3, valoff:D4)
  1354.         ;
  1355.         ;   list:    list to queue the object in
  1356.         ;   start:    sptr to start search at (NULL=beginning of list)
  1357.         ;   sptr:    pointer to the structure to queue, where
  1358.         ;   off:    offset into the structure where the embedded Node is
  1359.         ;   valoff:    offset into structure where the longword holding
  1360.         ;        the sorting priority of the object is.
  1361.         ;
  1362.         ;   The list is already assumed to be sorted.  The search
  1363.         ;   progresses either forward or reverse along the list until
  1364.         ;   the proper place is found, then the object is inserted into
  1365.         ;   the list.  The object is placed AFTER any objects of equal
  1366.         ;   priority (whether the list is searched forward or backwards).
  1367.  
  1368. _lEnqueueLong:
  1369.         movem.l D3/A2/A3,-(sp)
  1370.         moveq.l #0,D3
  1371.         bra    .eol1
  1372. _lEnqueueOffLong:
  1373.         movem.l D3/A2/A3,-(sp)
  1374. .eol1        move.l    D2,A3        ; A3 = structure to add
  1375.         move.l    D1,A2        ; A2 = roving structure in search
  1376.         tst.l    D1
  1377.         bne    .eol2
  1378.         move.l    D0,A2        ; use list head instead
  1379.         move.l    (A2),A1
  1380.         tst.l    (A1)
  1381.         beq    .eol100     ; add structure to empty list
  1382.         move.l    A1,A2
  1383.         sub.l    D3,A2        ; retrieve structure pointer
  1384.  
  1385.         ;   D0 = D4(A3)
  1386.         ;   D3 = offset into A2/A3 of node
  1387.         ;   D4 = offset into A2/A3 of longword value
  1388.         ;   A2 = roving structure ptr
  1389.         ;   A3 = structure to add
  1390.         ;
  1391.         ;   Sequence:    if D4(A3) > D4(A2), forward search
  1392.         ;        if D4(A3) < D4(A2), reverse search
  1393.  
  1394. .eol2        move.l    (A3,D4.L),D0    ; Search forwards or backwards?
  1395.         cmp.l    (A2,D4.L),D0
  1396.         blt    .eol50
  1397. .eol10        move.l    (A2,D3.L),A2    ; SEARCH FORWARDS (A2 = next node)
  1398.         tst.l    (A2)            ; reached list tail
  1399.         beq    .eol30        ; Add to tail
  1400.         sub.l    D3,A2        ; A2 = structure
  1401.         cmp.l    (A2,D4.L),D0
  1402.         bge    .eol10        ; loop while value > roving_value
  1403.         add.l    D3,A2        ; ADDBEFORE current node, A2 = listnode
  1404.         add.l    D3,A3        ; A3 = node to add
  1405.  
  1406.         move.l    A2,(A3)         ; INSERT BEFORE (listnode:A2, node:A3)
  1407.         move.l    4(A2),A0        ; A0 is node before A2  (seq A0-A3-A2)
  1408.         move.l    A0,4(A3)
  1409.         move.l    A3,4(A2)
  1410.         move.l    A3,(A0)
  1411.         bra    .eolend
  1412.                     ; (A2 points to lh_Tail here)
  1413. .eol30        move.l    4(A2),A2        ; ADDTOEND, A2 = tail element
  1414.         bra    .eol100
  1415. .eol50        move.l    4(A2,D3.L),A2   ;SEARCH BACKWARDS (A2 = prev. node)
  1416.         tst.l    4(A2)           ;reached list head .. AddHead()
  1417.         beq    .eol100
  1418.         sub.l    D3,A2        ;A2 = structure pointer
  1419.         cmp.l    (A2,D4.L),D0    ;loop while value < roving_value
  1420.         blt    .eol50
  1421.         add.l    D3,A2        ;add after NODE A2
  1422. .eol100     add.l    D3,A3        ;INSERT AFTER(list/node:A2, structure:A3)
  1423.         move.l    (A2),A0
  1424.         move.l    A0,(A3)
  1425.         move.l    4(A0),4(A3)
  1426.         move.l    A3,(A2)
  1427.         move.l    A3,4(A0)
  1428. .eolend     movem.l (sp)+,D3/A2/A3
  1429.         rts
  1430.  
  1431.         ;   SEARCHFWDLIST[OFF](list:D0, func:D1, [offset:A0,] funcarg:A1)
  1432.         ;   SEARCHRVSLIST[OFF](list:D0, func:D1, [offset:A0,] funcarg:A1)
  1433.         ;
  1434.         ;    Get head/tail of list then call Search???Node
  1435.  
  1436. _lSearchFwdList:
  1437.         sub.l    A0,A0
  1438. _lSearchFwdListOff:
  1439.         movem.l D2-D5/A2/A3/A6,-(sp)
  1440.         move.l    D0,A2
  1441.         move.l    (A2),A2             ; get head of list
  1442.         tst.l    (A2)                ; empty list?
  1443.         bne    SFN
  1444.         bra    .sfn0
  1445.  
  1446. _lSearchRvsList:
  1447.         sub.l    A0,A0
  1448. _lSearchRvsListOff:
  1449.         movem.l D2-D5/A2/A3/A6,-(sp)
  1450.         move.l    D0,A2
  1451.         move.l    8(A2),A2            ; get tail of list
  1452.         tst.l    4(A2)               ; empty list?
  1453.         bne    SRN
  1454.         bra    .sfr0
  1455.  
  1456.         ;   For compatibility with various C compilers, neither
  1457.         ;   A4 or A5 is touched.  D2,D3, and A6 are also assumed
  1458.         ;   to be destroyed by the function.
  1459.         ;
  1460.         ;   The search ends when the function returns a non-NULL
  1461.         ;   value or the list is exhausted (NULL is returned)
  1462.         ;
  1463.         ;   SEARCHFWDNODE(sptr:D0, func:D1, offset:A0, funcarg:A1)
  1464.  
  1465.  
  1466. _lSearchFwdNode:
  1467.         sub.l    A0,A0
  1468. _lSearchFwdNodeOff:
  1469.         movem.l D2-D5/A2/A3/A6,-(sp)
  1470.         move.l    D0,A2
  1471. SFN:        move.l    D1,A3
  1472.         move.l    A0,D4
  1473.         move.l    A1,D5
  1474.         move.l    A2,D0            ; test for initial NULL
  1475.         beq    .sfndone
  1476.         adda.l    D4,A2
  1477. .sfnloop    suba.l    D4,A2
  1478.         move.l    D5,-(sp)            ; call function(sptr, funcarg)
  1479.         move.l    A2,-(sp)
  1480.         jsr    (A3)
  1481.         addq.l    #8,sp
  1482.         tst.l    D0            ; non-zero ret. value
  1483.         bne    .sfndone
  1484.         adda.l    D4,A2            ; GetSuccOff()
  1485.         move.l    (A2),A2
  1486.         tst.l    (A2)
  1487.         bne    .sfnloop
  1488. .sfn0        moveq.l #0,D0
  1489. .sfndone    movem.l (sp)+,D2-D5/A2/A3/A6
  1490.         rts
  1491.  
  1492.         ;   SEARCHRVSNODE(node:D0, func:D1, offset:A0, funcarg:A1)
  1493.  
  1494. _lSearchRvsNode:
  1495.         sub.l    A0,A0
  1496.  
  1497. _lSearchRvsNodeOff:
  1498.         movem.l D2-D5/A2/A3/A6,-(sp)
  1499.         move.l    D0,A2
  1500. SRN:        move.l    D1,A3
  1501.         move.l    A0,D4
  1502.         move.l    A1,D5
  1503.         move.l    A2,D0            ; test for initial NULL
  1504.         beq    .sfrdone
  1505.         adda.l    D4,A2
  1506. .sfrloop    suba.l    D4,A2
  1507.         move.l    D5,-(sp)            ; call function(sptr, funcarg)
  1508.         move.l    A2,-(sp)            ; args also in A2 and D5
  1509.         jsr    (A3)
  1510.         addq.l    #8,sp
  1511.         tst.l    D0            ; non-zero ret. value
  1512.         bne    .sfrdone
  1513.         adda.l    D4,A2            ; GetPredOff()
  1514.         move.l    4(A2),A2
  1515.         tst.l    4(A2)
  1516.         bne    .sfrloop
  1517. .sfr0        moveq.l #0,D0
  1518. .sfrdone    movem.l (sp)+,D2-D5/A2/A3/A6
  1519.         rts
  1520.  
  1521. \Rogue\Monster\
  1522. else
  1523.   echo "will not over write src/lists.asm"
  1524. fi
  1525. if [ `wc -c src/lists.asm | awk '{printf $1}'` -ne 7630 ]
  1526. then
  1527. echo `wc -c src/lists.asm | awk '{print "Got " $1 ", Expected " 7630}'`
  1528. fi
  1529. if `test ! -s src/timedate.c`
  1530. then
  1531. echo "writing src/timedate.c"
  1532. cat > src/timedate.c << '\Rogue\Monster\'
  1533.  
  1534. /*
  1535.  *  DATETOS.C
  1536.  *
  1537.  *  leap year:    every four years but 3 out of 4 century marks are not leap years
  1538.  *        (2000 is) the year 0 was.  year&3==0 is
  1539.  *  timestamp is since 1978
  1540.  *
  1541.  *  valid range:    Jan 1 1976    to  Dec 31 2099
  1542.  */
  1543.  
  1544. #include <local/typedefs.h>
  1545.  
  1546. static char dim[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  1547. static char *Month[12] = { "Jan","Feb","Mar","Apr","May","Jun","Jul",
  1548.                "Aug","Sep","Oct","Nov","Dec" };
  1549.  
  1550. char *
  1551. lDateToS(date, str, ctl)
  1552. DATESTAMP *date;
  1553. char *str;
  1554. char *ctl;
  1555. {
  1556.     long days, years;
  1557.     short leap, month;
  1558.  
  1559.     if (ctl == NULL)
  1560.     ctl = "D M Y h:m:s";
  1561.     days = date->ds_Days + 731;         /*    1976        */
  1562.     years = days / (365*3+366);             /*  #quad yrs   */
  1563.     days -= years * (365*3+366);
  1564.     leap = (days < 366);                    /*  is a leap yr*/
  1565.     years = 1976 + 4 * years;
  1566.     if (!leap) {
  1567.     days -= 366;
  1568.     ++years;
  1569.     }
  1570.     years += days / 365;
  1571.     days -= (days / 365) * 365;
  1572.     for (month = 0; (month==1) ? (days >= 28 + leap) : (days >= dim[month]); ++month)
  1573.     days -= (month==1) ? (28 + leap) : dim[month];
  1574.     {
  1575.     register short i = 0;
  1576.     for (; *ctl; ++ctl) {
  1577.         switch(*ctl) {
  1578.         case 'h':
  1579.         utos(str+i, 1, 2, date->ds_Minute / 60);
  1580.         /*sprintf(str+i, "%02d", date->ds_Minute / 60);*/
  1581.         break;
  1582.         case 'm':
  1583.         utos(str+i, 1, 2, date->ds_Minute % 60);
  1584.         /*sprintf(str+i, "%02d", date->ds_Minute % 60);*/
  1585.         break;
  1586.         case 's':
  1587.         utos(str+i, 1, 2, date->ds_Tick / 50 % 60);
  1588.         /*sprintf(str+i, "%02d", date->ds_Tick / 50 % 60);*/
  1589.         break;
  1590.         case 'Y':
  1591.         utos(str+i, 0, 4, years);
  1592.         /*sprintf(str+i, "%ld", years);*/
  1593.         break;
  1594.         case 'M':
  1595.         strcpy(str+i, Month[month]);
  1596.         break;
  1597.         case 'D':
  1598.         utos(str+i, 0, 2, days+1);
  1599.         /*sprintf(str+i,"%2ld", days+1);*/
  1600.         break;
  1601.         default:
  1602.         str[i] = *ctl;
  1603.         str[i+1] = 0;
  1604.         break;
  1605.         }
  1606.         i += strlen(str+i);
  1607.     }
  1608.     }
  1609.     return(str);
  1610. }
  1611.  
  1612. utos(buf, zfill, flen, val)
  1613. register char *buf;
  1614. register short flen;
  1615. {
  1616.     buf[flen] = 0;
  1617.     while (flen--) {
  1618.     if (val)
  1619.         buf[flen] = '0' + (val % 10);
  1620.     else
  1621.         buf[flen] = (zfill) ? '0' : ' ';
  1622.     val /= 10;
  1623.     }
  1624. }
  1625.  
  1626. #define BTOC(bptr)    ((long)(bptr) << 2)
  1627. #define CTOB(cptr)    ((long)(cptr) >> 2)
  1628.  
  1629. #ifndef ACTION_SET_DATE
  1630. #define ACTION_SET_DATE 34
  1631. #endif
  1632.  
  1633. typedef struct StandardPacket STDPKT;
  1634. typedef struct MsgPort          MSGPORT;
  1635.  
  1636. extern void *AllocMem();
  1637.  
  1638. lSetFileDate(file, date)
  1639. char *file;
  1640. DATESTAMP *date;
  1641. {
  1642.     register STDPKT *packet;
  1643.     register char   *buf;
  1644.     register PROC   *proc;
  1645.     long    result;
  1646.     long    lock;
  1647.  
  1648.     {
  1649.     register long flock = Lock(file, SHARED_LOCK);
  1650.     register short i;
  1651.     register char *ptr = file;
  1652.  
  1653.     if (flock == NULL)
  1654.         return(NULL);
  1655.     lock = ParentDir(flock);
  1656.     UnLock(flock);
  1657.     if (!lock)
  1658.         return(NULL);
  1659.     for (i = strlen(ptr) - 1; i >= 0; --i) {
  1660.         if (ptr[i] == '/' || ptr[i] == ':')
  1661.         break;
  1662.     }
  1663.     file += i + 1;
  1664.     }
  1665.     proc   = (PROC *)FindTask(NULL);
  1666.     packet = (STDPKT   *)AllocMem(sizeof(STDPKT), MEMF_CLEAR|MEMF_PUBLIC);
  1667.     buf = AllocMem(strlen(file)+2, MEMF_PUBLIC);
  1668.     strcpy(buf+1,file);
  1669.     buf[0] = strlen(file);
  1670.  
  1671.     packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
  1672.     packet->sp_Pkt.dp_Link = &packet->sp_Msg;
  1673.     packet->sp_Pkt.dp_Port = &proc->pr_MsgPort;
  1674.     packet->sp_Pkt.dp_Type = ACTION_SET_DATE;
  1675.     packet->sp_Pkt.dp_Arg1 = NULL;
  1676.     packet->sp_Pkt.dp_Arg2 = (long)lock;        /*  lock on parent dir of file  */
  1677.     packet->sp_Pkt.dp_Arg3 = (long)CTOB(buf);   /*  BPTR to BSTR of file name   */
  1678.     packet->sp_Pkt.dp_Arg4 = (long)date;        /*  APTR to datestamp structure */
  1679.     PutMsg(((LOCK *)BTOC(lock))->fl_Task, packet);
  1680.     WaitPort(&proc->pr_MsgPort);
  1681.     GetMsg(&proc->pr_MsgPort);
  1682.     result = packet->sp_Pkt.dp_Res1;
  1683.     FreeMem(packet, sizeof(STDPKT));
  1684.     FreeMem(buf, strlen(file)+2);
  1685.     UnLock(lock);
  1686.     return(result);
  1687. }
  1688.  
  1689. \Rogue\Monster\
  1690. else
  1691.   echo "will not over write src/timedate.c"
  1692. fi
  1693. if [ `wc -c src/timedate.c | awk '{printf $1}'` -ne 3802 ]
  1694. then
  1695. echo `wc -c src/timedate.c | awk '{print "Got " $1 ", Expected " 3802}'`
  1696. fi
  1697. if `test ! -s src/oldfile.c`
  1698. then
  1699. echo "writing src/oldfile.c"
  1700. cat > src/oldfile.c << '\Rogue\Monster\'
  1701.  
  1702. #include <local/res.h>
  1703.  
  1704. #define SFILE    struct _SFILE
  1705. #define RFILE    struct _RFILE
  1706. #define FTABLE    struct _FTABLE
  1707. #define HTABLE    struct _HTABLE
  1708.  
  1709. SFILE {
  1710.     long    XLock[2];
  1711.     long    Fh;     /*  associated fh or lock    */
  1712.     uword   Flags;    /*  HAVHANDLE, HAVLOCK        */
  1713.     long    Swapped;    /*  bytes swapped        */
  1714.     long    FileSize;    /*  current file size        */
  1715.     long    Free;    /*  bytes free            */
  1716.     long    Link[32];    /*  swap area free lists    */
  1717.     char    *Name;    /*  file name            */
  1718. };
  1719.  
  1720. RFILE {
  1721.     long    XLock[2];
  1722.     long    Fh;     /*  associated fh or lock    */
  1723.     long    HTsize;    /*  hash table size in file    */
  1724.     long    Loaded;    /*  bytes loaded        */
  1725.     long    Swapped;    /*  bytes swapped        */
  1726.     uword   Flags;    /*  HAVHANDLE, HAVLOCK        */
  1727.     uword   HTSize;    /*  pwr of 2, # of entries    */
  1728.     FTABLE  **HTab;    /*  [n]&3:0-mem 1-seek.  file access dict.  */
  1729.     HTABLE  **LTab;    /*  active resource access table        */
  1730.     char    *Name;    /*  file name            */
  1731. };
  1732.  
  1733. FTABLE {
  1734.     long    Next;    /*  Next entry 0-end, &3:0-mem 1-seek        */
  1735.     uword   Flags;    /*  all applicable flags, inc load state    */
  1736.     ubyte   NLen;    /*  name length                 */
  1737.     ubyte   TLen;    /*  type length                 */
  1738.     long    Seek;    /*  seek position in file            */
  1739.     long    Len;    /*  size of resource in file / htable ptr   */
  1740.     ubyte   Name[2];    /*  extend structure to [n]            */
  1741. };
  1742.  
  1743. HTABLE {
  1744.     long    Next;    /*  Next entry 0-end, &3:0-mem 1-swapped    */
  1745.     uword   Flags;    /*  all applicable flags, inc load state    */
  1746.     uword   Refs;
  1747.     long    Ptr;    /*  data ptr, swap ptr                */
  1748.     long    Func;    /*  control function                */
  1749. };
  1750.  
  1751. \Rogue\Monster\
  1752. else
  1753.   echo "will not over write src/oldfile.c"
  1754. fi
  1755. if [ `wc -c src/oldfile.c | awk '{printf $1}'` -ne 1623 ]
  1756. then
  1757. echo `wc -c src/oldfile.c | awk '{print "Got " $1 ", Expected " 1623}'`
  1758. fi
  1759. if `test ! -s src/oldfile.h`
  1760. then
  1761. echo "writing src/oldfile.h"
  1762. cat > src/oldfile.h << '\Rogue\Monster\'
  1763.  
  1764. /*
  1765.  *  FILE.H
  1766.  *
  1767.  *  Message Passing structure.
  1768.  */
  1769.  
  1770. #define RMSG struct _RMSG
  1771.  
  1772. RMSG {
  1773.     MSG     Mesg;    /*  exec message    */
  1774.     long    Arg1;
  1775.     long    Arg2;
  1776.     long    Arg3;
  1777.     long    Arg4;
  1778.     long    Res1;
  1779. };
  1780.  
  1781. #define RACT_GETRES    1   /*    (name,type,nmlen,tylen)     */
  1782. #define RACT_
  1783.  
  1784. extern PORT    ResPort;
  1785.  
  1786.  
  1787. \Rogue\Monster\
  1788. else
  1789.   echo "will not over write src/oldfile.h"
  1790. fi
  1791. if [ `wc -c src/oldfile.h | awk '{printf $1}'` -ne 319 ]
  1792. then
  1793. echo `wc -c src/oldfile.h | awk '{print "Got " $1 ", Expected " 319}'`
  1794. fi
  1795. if `test ! -s src/res.c`
  1796. then
  1797. echo "writing src/res.c"
  1798. cat > src/res.c << '\Rogue\Monster\'
  1799.  
  1800. /*
  1801.  *  RES.C
  1802.  *
  1803.  *  System Overview:
  1804.  *    GetRes()            -
  1805.  *    DupRes()            -
  1806.  *    FreeRes()           -
  1807.  *    FreeAllRes()        -
  1808.  *    ChownRes()          -
  1809.  *    UnLinkAllRes()      -
  1810.  *    ReLinkAllRes()      -
  1811.  *    SetResFlags()       -
  1812.  *    AddRes()            -
  1813.  *    RemRes()            -
  1814.  *    GetResInfo()        -
  1815.  *    GetResList()        -
  1816.  *    GetFileList()       -
  1817.  *    AddPrivResFile()    -
  1818.  *    RemPrivResFiles()   -
  1819.  *    AddGlobResFile()    -
  1820.  *    RemGlobResFiles()   -
  1821.  *    AddResSwapDir()     -
  1822.  *    RemResSwapDirs()    -
  1823.  *
  1824.  */
  1825.  
  1826. #include <local/typedefs.h>
  1827. #include <local/ipc.h>
  1828. #include <local/res.h>
  1829. #include "/src/ires.h"
  1830.  
  1831. static long SysLock[2] = { 0, 0 };
  1832.  
  1833. extern TML *GetTML();
  1834.  
  1835. /*
  1836.  *  Search order:   Private-mem, Private-disk, System-mem, System-disk,
  1837.  *            OtherTaskGlob-mem, OtherTaskGlob-disk
  1838.  */
  1839.  
  1840. APTR
  1841. GetRes(name)
  1842. char *name;
  1843. {
  1844.     TML *tml = GetTML();
  1845.  
  1846.  
  1847.  
  1848.  
  1849.     resptr= GetRes(resnametype)             char *resnametype;
  1850.  
  1851.     This function retrieves the requested resource, doing any
  1852.     translations required to get the resource into the requested
  1853.     type.  NULL is returned if the resource could not be found
  1854.     or could not be translated to the requested type.
  1855.  
  1856.     In-Memory private resources are searched first, then the private
  1857.     resource files for the task, then In-Memory system resources, then
  1858.     the global resource files for the system.  Openning an already-open
  1859.     resource causes one of two actions depending on whether the resource
  1860.     is shared or not.  If shared, the reference count is simply
  1861.     incremented, otherwise a private copy of the resource is made.
  1862.  
  1863.     Example:    Win = GetRes("Charlie.Window");
  1864.  
  1865.     resptr2 = DupRes(resptr1)               APTR resptr1, resptr2;
  1866.  
  1867.     This call duplicates a resource.  If the resource is shared
  1868.     resptr2 will be the same as resptr1 and the reference count will
  1869.     be bumped.  Otherwise, a new resource data area is allocated and
  1870.     the old copied to the new.
  1871.  
  1872.     Things like fixing pointers and such within a resource that is
  1873.     physically duplicated are handled by the interface code (since
  1874.     raw resources do not contain pointers, only VIRTUAL resources
  1875.     will contain pointers and all VIRTUAL resources have some
  1876.     interface code).
  1877.  
  1878.     error = FreeRes(resptr)
  1879.  
  1880.     Free a resource that you retrieved via GetRes().  Only the task
  1881.     that owns the resource may free it (though several tasks may own
  1882.     a resource through duplication and ownership changes).    1 is
  1883.     returned on success, 0 on error.
  1884.  
  1885.     That is, if task #1 GetRes()'s the resource and duplicates it once,
  1886.     then task #2 duplicates it once, task #1 must call FreeRes() twice
  1887.     and task #2 must call FreeRes() once.  Ownership is strictly
  1888.     tracked.
  1889.  
  1890.     numres= FreeAllRes(task)
  1891.  
  1892.     Free all resources associated with the specified task (NULL for
  1893.     self).
  1894.  
  1895.     error = ChownRes(resptr, fromtask, totask)
  1896.  
  1897.     Change ownership of a resource from the source task to the
  1898.     destination task.  The resource must be owned by the source
  1899.     task or an error will occur (0 return value).  1 is returned
  1900.     on success.  NULL may be specified for either or both tasks
  1901.     and means the calling task.
  1902.  
  1903.     handle= UnLinkAllRes(task)
  1904.  
  1905.     Unlink all resources associated with the specified task (NULL
  1906.     for self) and return a handle representing those resources.
  1907.  
  1908.     This is useful for shells and such to keep their resources from
  1909.     getting removed by commands they run.  Combined with the NUNLINK
  1910.     flag one can pass resources to a Command and keep the rest out of
  1911.     reach.
  1912.  
  1913.     (void)  ReLinkAllRes(handle, task)
  1914.  
  1915.     Link all the resources represented by the handle to the specified
  1916.     task (NULL for self).
  1917.  
  1918.     oldfl = SetResFlags(resptr, newflags, flagsmask)
  1919.  
  1920.     Modify the flags associated with a resource.  NOTE:  If multiple
  1921.     references to a shared resource exist, all are modified.  Some
  1922.     modifications may be disallowed by the system.    This call is
  1923.     normally used to modify the LOCKED and SWAPABLE flags (note that
  1924.     the SWAPABLE flag can be changed back and forth only for resource
  1925.     which support it).
  1926.  
  1927.     error = AddRes(resnametype, flags, ptr, ctlcode);
  1928.                             char *resnametype;
  1929.                             long flags;
  1930.                             APTR ptr;
  1931.                             long (*ctlcode)();
  1932.  
  1933.     Add a resource to the system.  The resource is placed either in
  1934.     the task's privately accessable in-memory resource list or
  1935.     in the system global accessable in-memory resource list depending
  1936.     on the specified flags.  One may now GetRes() the resource.
  1937.  
  1938.     ONLY VIRTUAL RESOURCES MAY BE ADDED IN THIS WAY.  The VIRTUAL
  1939.     and LOCKED flags are automatically set.
  1940.  
  1941.     If flags specifies a VIRTUAL resource
  1942.  
  1943.     error = RemRes(resname)
  1944.  
  1945.     Remove the specified resource.    An error will occur and the resource
  1946.     will not be removed (1) if it does not exist in memory, or (2) it
  1947.     is currently being referenced.    (Note: the resource is removed even
  1948.     if it is swapped or locked).
  1949.  
  1950.     error = GetResInfo(resname, &flags, &bytes)
  1951.  
  1952.     Get information on a resource.    Information may not exist for a
  1953.     resource if it is not currently in memory and would have to be
  1954.     translated to get to the right type.
  1955.  
  1956.     error = GetResList(wildcard, from, &av, &ac);
  1957.  
  1958.     from:    mask, bit 0  search private list
  1959.               1  search system list
  1960.               2  <not used>
  1961.               3  search in-memory private list
  1962.               4  search in-memory global list
  1963.  
  1964.     Return an ARGC/ARGV list of resource names.  Note that some names
  1965.     might be duplicated if searching multiple lists.  Restricting the
  1966.     search to in-memory lists give resources which are already in
  1967.     memory (but might be swapped out or removed at any time for those
  1968.     with no references)
  1969.  
  1970.                  RESOURCE FILES
  1971.  
  1972.     error = GetFileList(wildcard, from, &av, &ac);
  1973.  
  1974.     from:    mask, bit 0  search private list
  1975.               1  search system list
  1976.               2  search swap list
  1977.  
  1978.     Return an ARGC/ARGV list of the files which match the specified
  1979.     wildcard from the private list, system list, or system swap dir
  1980.     list (in which case you get directory names).  This list has been
  1981.     allocated, and can be freed as follows:
  1982.  
  1983.         Loop through all entries for (i = 0; i < ac; ++i)
  1984.                     FreeMem(av[i], strlen(av[i])+1);
  1985.         Free the array itself:  FreeMem(av, sizeof(char *) * (ac+1));
  1986.  
  1987.     num   = AddPrivResFile(filename, pri)
  1988.  
  1989.     Add a file name to the list of resource files for this task.  These
  1990.     are scanned before global files when a resource is requested.  All
  1991.     files in the list are write protected (i.e. a shared lock is kept
  1992.     for each file).  Thus, such files cannot be updated until removed
  1993.     from the list.
  1994.  
  1995.     Can also be used to modify the priority of an existing file
  1996.  
  1997.     num   = RemPrivResFiles(wildcard)
  1998.  
  1999.     Remove zero or more file names from the list of resource files for
  2000.     this task.  A wildcard pattern (* and ?) is accepted.
  2001.  
  2002.     Note for command processors:    commands you run might execute
  2003.     this command for *.
  2004.  
  2005.     num   = AddGlobResFile(filename, pri)
  2006.  
  2007.     Same as AddPrivResFile() but applies to the system list, which is
  2008.     searched last and by any requesting task.  Wildcard file names are
  2009.     NOT accepted.  The file need not exist at this time, and references
  2010.     to unmounted volumes are allowed.
  2011.  
  2012.     Can also be used to modify the priority of an existing entry
  2013.  
  2014.     num   = RemGlobResFiles(wildcard)
  2015.  
  2016.     Remove zero or more resource files from the global list.  Again,
  2017.     a wildcard filename is accepted.
  2018.  
  2019.     num   = AddResSwapDir(dirname, pri, maxkbytes)      char *dirname;
  2020.                             char pri;
  2021.                             long maxkbytes
  2022.  
  2023.     Add a directory to the list of directories the resource system
  2024.     can swap to.  The maximum number of KBytes of material allowed
  2025.     in the directory should be specified.  You can also use this
  2026.     call to modify the priority and maxkbytes for an entry.
  2027.  
  2028.     The highest priority directories are used before lower priority
  2029.     directories.  Not all directories need be mounted, but if a swapin
  2030.     occurs from an unmounted directory a requester will appear.
  2031.  
  2032.     A lock is kept on each specified directory.
  2033.  
  2034.     num   = RemResSwapDirs(wildcard)
  2035.  
  2036.     Remove directories associated with the resource swap areas.
  2037.  
  2038.  
  2039.                 RESOURCE FILE IFF FORMAT
  2040.  
  2041.  
  2042.  
  2043.  
  2044. static
  2045. TML *
  2046. GetTML()
  2047. {
  2048.     TML *tml = GetTaskData(RESMLNAME, sizeof(TML));
  2049.     if (tml && !tml->RFList.mlh_Head) {
  2050.     NewList(&tml->RENList);
  2051.     NewList(&tml->RFList);
  2052.     }
  2053.     return(tml);
  2054. }
  2055.  
  2056. \Rogue\Monster\
  2057. else
  2058.   echo "will not over write src/res.c"
  2059. fi
  2060. if [ `wc -c src/res.c | awk '{printf $1}'` -ne 8107 ]
  2061. then
  2062. echo `wc -c src/res.c | awk '{print "Got " $1 ", Expected " 8107}'`
  2063. fi
  2064. echo "Finished archive 2 of 3"
  2065. # if you want to concatenate archives, remove anything after this line
  2066. exit
  2067. -- 
  2068. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  2069. Have five nice days.
  2070.